﻿using System;
using System.Collections.Generic;

using System.Text;
using System.Drawing;
using System.Web.UI;
using System.ComponentModel;
using TA.Turbo.Design;



namespace TA.Turbo.Controls
{
	/// <summary>
	/// Modal popup panel which can be used to display a dialog box.
	/// </summary>
	public class ModalPopupPanel : BasePopupControl
	{
		#region PUBLIC
		#region INIT
		/// <summary>
		/// Ctor.
		/// </summary>
		public ModalPopupPanel()
		{
			_okControls = new MultiControlValue<BaseCommandControl>(this);
			_openControls = new MultiControlValue<BaseCommandControl>(this);
			_cancelControls = new MultiControlValue<BaseCommandControl>(this);
		}
		#endregion
		#region PROPS
		#region DEF
		/// <summary>
		/// Props.
		/// </summary>
		protected static new Properties _clientProperties = Define(BasePopupControl._clientProperties,
			new BasePropertyDefinition[] {
				new EnumPropertyDefinition<BlockingMode>("Blocking", "B", BlockingMode.All),
				new PropertyDefinition<string>("OpenArgument", "OA", null),
				new PropertyDefinition<string>("Title", "Ti", null) { IsUsedByClient = false, },
				new PropertyDefinition<string>("TitleCssClass", "TC", "title") { IsUsedByClient = false, },
				new PropertyDefinition<string>("BodyCssClass", "BC", "body") { IsUsedByClient = false, },
				new ControlIdPropertyDefinition("DefaultButtonId", "DB", null),
			});
		/// <summary>
		/// Props.
		/// </summary>
		public override Properties ClientProperties
		{
			get
			{
				return _clientProperties;
			}
		}
		#endregion
		/// <summary>
		/// Controls how this control blocks the background to make itself modal.
		/// </summary>
		[DefaultValue(BlockingMode.All)]
		public BlockingMode Blocking
		{
			get
			{
				return GetProperty<BlockingMode>("Blocking");
			}
			set
			{
				ViewState["Blocking"] = value;
			}
		}
		/// <summary>
		/// When this control is opened from multiple places, this property holds a value indicating which action triggered it.
		/// </summary>
		[Browsable(false)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public string OpenArgument
		{
			get
			{
				return GetProperty<string>("OpenArgument");
			}
			set
			{
				ViewState["OpenArgument"] = value;
			}
		}
		/// <summary>
		/// Comma-separated list of IDs of controls that, when clicked, open this control.
		/// </summary>
		[DefaultValue("")]
		public string OpenControlIds
		{
			get
			{
				return _openControls.Value;
			}
			set
			{
				_openControls.Value = value;
			}
		}
		/// <summary>
		/// Modifiable collection of IDs of controls that, when clicked, open this control.
		/// </summary>
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		[Editor(typeof(ControlIdCollectionEditor<CommandControlIdLister>), typeof(System.Drawing.Design.UITypeEditor))]
		public List<string> OpenControlIdList
		{
			get
			{
				return _openControls.ValueList;
			}
		}
		/// <summary>
		/// Modifiable collection of controls that, when clicked, open this control.
		/// </summary>
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		[Browsable(false)]
		public List<BaseCommandControl> OpenControlList
		{
			get
			{
				return this._openControls.ControlList;
			}
		}
		/// <summary>
		/// Comma-separated list of IDs of controls that, when clicked, cause a post which closes this control when validated.
		/// </summary>
		[DefaultValue("")]
		public string OkControlIds
		{
			get
			{
				return _okControls.Value;
			}
			set
			{
				_okControls.Value = value;
			}
		}
		/// <summary>
		/// Modifiable collection of IDs of controls that, when clicked, cause a post which closes this control when validated.
		/// </summary>
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		[Editor(typeof(ControlIdCollectionEditor<CommandControlIdLister>), typeof(System.Drawing.Design.UITypeEditor))]
		public List<string> OkControlIdList
		{
			get
			{
				return _okControls.ValueList;
			}
		}
		/// <summary>
		/// Modifiable collection of controls that, when clicked, cause a post which closes this control when validated.
		/// </summary>
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		[Browsable(false)]
		public List<BaseCommandControl> OkControlList
		{
			get
			{
				return _okControls.ControlList;
			}
		}
		/// <summary>
		/// Comma-separated list of IDs of controls that, when clicked, close this control.
		/// </summary>
		[DefaultValue("")]
		public string CancelControlIds
		{
			get
			{
				return _cancelControls.Value;
			}
			set
			{
				_cancelControls.Value = value;
			}
		}
		/// <summary>
		/// Modifiable collection of IDs of controls that, when clicked, close this control.
		/// </summary>
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		[Editor(typeof(ControlIdCollectionEditor<CommandControlIdLister>), typeof(System.Drawing.Design.UITypeEditor))]
		public List<string> CancelControlIdList
		{
			get
			{
				return _cancelControls.ValueList;
			}
		}
		/// <summary>
		/// Modifiable collection of controls that, when clicked, close this control.
		/// </summary>
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		[Browsable(false)]
		public List<BaseCommandControl> CancelControlList
		{
			get
			{
				return _cancelControls.ControlList;
			}
		}
		/// <summary>
		/// The title of this control.
		/// </summary>
		[DefaultValue("")]
		public string Title
		{
			get
			{
				return GetProperty<string>("Title");
			}
			set
			{
				ViewState["Title"] = value;
			}
		}
		/// <summary>
		/// The CSS class to be applied to the title element.
		/// </summary>
		[CssClassProperty]
		[DefaultValue("title")]
		public string TitleCssClass
		{
			get
			{
				return GetProperty<string>("TitleCssClass");
			}
			set
			{
				ViewState["TitleCssClass"] = value;
			}
		}
		/// <summary>
		/// The CSS class to be applied to the body of this control.
		/// </summary>
		[CssClassProperty]
		[DefaultValue("body")]
		public string BodyCssClass
		{
			get
			{
				return GetProperty<string>("BodyCssClass");
			}
			set
			{
				ViewState["BodyCssClass"] = value;
			}
		}
		/// <summary>
		/// The ID of the button which will be clicked when a user pushes "Enter" while focused on a control inside this control.
		/// </summary>
		[IDReferenceProperty]
		[TypeConverter(typeof(ControlIdConverter<CommandControlIdLister>))]
		[DefaultValue("")]
		public string DefaultButtonId
		{
			get
			{
				return GetProperty<string>("DefaultButtonId");
			}
			set
			{
				ViewState["DefaultButtonId"] = value;
			}
		}
		#endregion
		#endregion
		#region INTERNAL
		#region VARS
		MultiControlValue<BaseCommandControl> _okControls, _openControls, _cancelControls;
		#endregion
		#region METHODS
		#region INIT
		/// <summary>
		/// Init.
		/// </summary>
		/// <param name="e"></param>
		protected override void OnInit(EventArgs e)
		{
			base.OnInit(e);

			if (this.TPage != null)
			{
				foreach (BaseCommandControl c in OpenControlList)
				{
					c.Click.Client = GetShowHideScript(true) + c.Click.GetEventClientScript(null);
				}
				foreach (BaseCommandControl c in CancelControlList)
				{
					c.Click.Client = GetShowHideScript(false) + c.Click.GetEventClientScript(null);
				}
				foreach (BaseCommandControl c in OkControlList)
				{
					BaseCommandControl bc = (BaseCommandControl)c;
					c.Click.Server += new EventHandler<EventArgs>(this.okControl_Click);
					PostScenario psOkClick = new PostScenario { CausesValidation = false };
					psOkClick.ReturnControls.Add(new ControlReference
					{
						ControlId = this.UniqueID,
						Value = false,
						Properties = "Shown"
					});
					c.Click.EnsureScenario(psOkClick);
				}
			}
		}
		/// <summary>
		/// Registers <see cref="Script.Math"/>, <see cref="Script.CSS"/>, <see cref="Script.SizePos"/> and ModalPopupPanel.js.
		/// </summary>
		protected internal override void RegisterIncludes(IncludeCollection includes)
		{
			base.RegisterIncludes(includes);

			includes.Add(Script.Math);
			includes.Add(Script.CSS);
			includes.Add(Script.SizePos);
			includes.Add(Script.ElementSearch);
			includes.Add(Script.String_IsNullOrEmpty);
			includes.Add(Script.Array_IndexOf);
			includes.Add(Script.Array_Remove);
			includes.Add(new ScriptResourceInclude("TA.Turbo.Res.JS.Popup.ModalPopupPanel.js", typeof(ModalPopupPanel)));
		}
		#endregion
		#region HANDLERS
		void okControl_Click(object sender, EventArgs e)
		{
			if (this.TPage.CurrentScenario.CausesValidation)
			{
				if (this.TPage.IsValid)
					this.Shown = false;
			}
			else
				Shown = false;
		}
		#endregion
		#region RENDER
		/// <summary>
		/// Adds position style, depending on requesting browser.
		/// </summary>
		/// <param name="writer"></param>
		protected override void AddAttributesToRender(HtmlTextWriter writer)
		{
			if (!this.get_IsDesignMode())
			{
				if (this.Page.Request.Browser.Browser == "IE" && this.Page.Request.Browser.MajorVersion <= 6)
					writer.AddStyleAttribute(HtmlTextWriterStyle.Position, "absolute");
				else
					writer.AddStyleAttribute(HtmlTextWriterStyle.Position, "fixed");
			}

			base.AddAttributesToRender(writer);
		}
		/// <summary>
		/// Renders begin tag, title and the begin tag of the body.
		/// </summary>
		/// <param name="writer"></param>
		protected override void RenderBeginTag(HtmlTextWriter writer)
		{
			base.RenderBeginTag(writer);

			writer.AddAttribute(HtmlTextWriterAttribute.Class, TitleCssClass);
			writer.AddAttribute("onselectstart", "return false;");
			writer.RenderBeginTag(HtmlTextWriterTag.Div);

			writer.RenderBeginTag(HtmlTextWriterTag.Span);
			writer.Write(Title);
			writer.RenderEndTag();

			writer.AddAttribute(HtmlTextWriterAttribute.Onclick, TPage.PrepareScript(this.GetShowHideScript(false)));
			writer.RenderBeginTag(HtmlTextWriterTag.A);
			writer.Write("&nbsp;");
			writer.RenderEndTag();

			writer.RenderEndTag();

			writer.AddAttribute(HtmlTextWriterAttribute.Class, BodyCssClass);
			writer.RenderBeginTag(HtmlTextWriterTag.Div);
		}
		/// <summary>
		/// Renders the end tag of the body.
		/// </summary>
		/// <param name="writer"></param>
		protected override void RenderEndTag(HtmlTextWriter writer)
		{
			writer.RenderEndTag();

			base.RenderEndTag(writer);
		}
		#endregion
		#endregion
		#endregion
	}
}
